#include <benchmark/benchmark.h>
#include "stdlib.h"
#include "stdio.h"
#include "util.h"

using namespace std;

int compare(const void *a, const void *b)
{
	int num1 = *(int *)a;
	int num2 = *(int *)b;
	if (num1 < num2)
	{
		return -1;
	}
	else if (num1 > num2)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

static void Bm_function_Mallocandfree(benchmark::State &state)
{
	const size_t size = state.range(0);
	for (auto _ : state)
	{
		void *result = malloc(size);
		benchmark::DoNotOptimize(result);
		free(result);
	}
	state.SetBytesProcessed(state.iterations() * size);
}

// 把str指向的字符串转化为浮点数
static void Bm_function_Strtod(benchmark::State &state)
{
	char str[] = "+2.86500000e+01";
	char *ptr;
	for (auto _ : state)
	{
		benchmark::DoNotOptimize(strtod(str, &ptr));
	}
	state.SetBytesProcessed(state.iterations());
}

static void Bm_function_Strtoul(benchmark::State &state)
{
	char str[] = "ff007dff";
	char *ptr;
	for (auto _ : state)
	{
		benchmark::DoNotOptimize(strtoul(str, &ptr, 10));
	}
	state.SetBytesProcessed(state.iterations());
}

static void Bm_function_Qsort(benchmark::State &state)
{

	int arr[] = {5, 3, 7, 1, 9};
	int n = sizeof(arr) / sizeof(arr[0]);
	for (auto _ : state)
	{
		qsort(arr, n, sizeof(int), compare);
	}
}

static void Bm_function_Getenv(benchmark::State &state)
{

	for (auto _ : state)
	{
		char *value = getenv("FREETYPE_PROPERTIES");
		benchmark::DoNotOptimize(value);
	}
}

static void Bm_function_Realpath(benchmark::State &state)
{
	const char *path = "/data/test.txt";
	char resolved_path[100];
	for (auto _ : state)
	{
		benchmark::DoNotOptimize(realpath(path, resolved_path));
	}
}

static void Bm_function_Atoi(benchmark::State &state)
{
	char s[] = "803149";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(atoi(s));
    }
    state.SetBytesProcessed(state.iterations());
}

MUSL_BENCHMARK_WITH_ARG(Bm_function_Mallocandfree, "MALLOC_FREE"); 
MUSL_BENCHMARK(Bm_function_Strtod);
MUSL_BENCHMARK(Bm_function_Strtoul);
MUSL_BENCHMARK(Bm_function_Qsort); 
MUSL_BENCHMARK(Bm_function_Getenv); 
MUSL_BENCHMARK(Bm_function_Realpath);
MUSL_BENCHMARK(Bm_function_Atoi);
